package com.lz.comm.widget.fragment

import android.os.Bundle
import android.os.Parcelable
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager
import androidx.lifecycle.Lifecycle

/**
 * Created by You on 2020-02-13.
 * 切换时保存fragment对象引用及状态, 切换时只触发onResume, 多用于主界面固定不变的Tab
 * (onAttach, onCreate,onCreateView, onDetaach, onDestory, ondestoryView只调用一次),
 * 内存不足或意外回收不保存(Fragment.SaveState)状态, 保存引用
 */
abstract class FragmentAdapter(manager: FragmentManager) : FragmentLayout.Adapter(manager) {

    override fun instantFragment(fm: FragmentLayout, position: Int) {
        if (mCurrentPosition == position) return
        val ft = mManager.beginTransaction()

        val itemId = getItemId(position)
        val name = makeFragmentName(fm.id, itemId)
        var fragment = mManager.findFragmentByTag(name)
        if (fragment != null) {
            ft.show(fragment)
            showExistFragment(fragment)
        } else {
            fragment = getItem(position)
            while (mFragments.size <= position) {
                mFragments.add(null)
            }
            mFragments[position] = fragment
            ft.add(fm.id, fragment, name)
        }
        fragment.setMenuVisibility(true)
        ft.setMaxLifecycle(fragment, Lifecycle.State.RESUMED)

        mCurrentFragment?.also {
            ft.hide(it)
            it.setMenuVisibility(false)
            ft.setMaxLifecycle(it, Lifecycle.State.STARTED)
        }

        mCurrentFragment = fragment
        mCurrentPosition = position
        ft.commitNowAllowingStateLoss()
    }

    override fun saveState(): Parcelable? = Bundle().also { state ->
        state.putInt("currentPosition", mCurrentPosition)
        for (i in mFragments.indices) {
            mFragments[i]?.also { mManager.putFragment(state, "$KEY$i", it) }
        }
    }

    override fun restoreState(state: Parcelable?, loader: ClassLoader?) {
        if (state != null) {
            val bundle = state as Bundle
            mCurrentPosition = bundle.getInt("currentPosition")
            for (key in bundle.keySet()) {
                if (key.startsWith(KEY)) {
                    val index = key.substring(KEY.length).toInt()
                    mManager.getFragment(bundle, key)?.also {
                        while (mFragments.size <= index) {
                            mFragments.add(null)
                        }
                        it.setMenuVisibility(false)
                        mFragments[index] = it
                    }
                }
            }
            val ft = mManager.beginTransaction()
            for (i in mFragments.indices) {
                mFragments[i]?.also {
                    if (i == mCurrentPosition) {
                        mCurrentFragment = it
                    } else {
                        ft.hide(it)
                        it.setMenuVisibility(false)
                        ft.setMaxLifecycle(it, Lifecycle.State.STARTED)
                    }
                }
            }
            ft.commitNowAllowingStateLoss()
        }
    }

    /**
     * 模块切换时，直接显示已经存在的fragment
     * @param f
     */
    protected open fun showExistFragment(f: Fragment) = Unit

    companion object {
        private const val KEY = "FragmentAdapter"
    }
}